#include "SSHQData.h"
#include<algorithm>
#include <sstream>
#include "his_stream.h"
#include "LogSubject.h"

#include "rapidjson/document.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
using namespace  RAPIDJSON_NAMESPACE;


CSSHQData::CSSHQData()
	: nExpired(0), nPort(0), nStatus(1)
	, nCollectTime(0), nCurTime(0)

{

}

CSSHQData::CSSHQData(unsigned int expired, std::string code, std::string sign, std::string ip, unsigned int port)
	: nExpired(expired), nPort(port), nStatus(1), strCode(code)
	, strSign(sign), strIP(ip), nCollectTime(0), nCurTime(0)
{

}

CSSHQData::CSSHQData(const CSSHQData& other)
{
	nCollectTime = other.nCollectTime ;
	nCurTime     = other.nCurTime     ;
	nExpired     = other.nExpired     ;
	strSign      = other.strSign      ;
	strIP        = other.strIP        ;
	nPort        = other.nPort        ;
	nStatus      = other.nStatus      ;
	strCode      = other.strCode      ;
	data          = other.data        ;

}


CSSHQData& CSSHQData::operator=(const CSSHQData& other)
{
	if (this == &other)
		return *this;
	
	nCollectTime  = other.nCollectTime;   
	nCurTime      = other.nCurTime    ;   
	nExpired      = other.nExpired    ;   
	strSign       = other.strSign     ;   
	strIP         = other.strIP       ;   
	nPort         = other.nPort       ;   
	nStatus       = other.nStatus     ;   
	strCode       = other.strCode     ;   
	data          = other.data        ;
	return *this;
}

CSSHQData::~CSSHQData()
{

}
bool CSSHQData::Update(ModualMsg* msg, bool& bChange)
{
	bChange = false;
	if (!msg) 
		return false;


	if (msg->nStatus == 1)
	{
		return false;
	}
	else if (msg->nStatus == 2)
	{
		nStatus = 0;
		return false;
	}
	else
	{
		Document doc;
		if (doc.Parse(msg->szText.c_str()).HasParseError())
			return false;

		Value::ConstMemberIterator itFind = doc.FindMember("data");
		if (itFind == doc.MemberEnd() || !itFind->value.IsString())
			return false;
		const char * strTmp = itFind->value.GetString();

		int sizeTotal = itFind->value.GetStringLength();

		nStatus = msg->nStatus;		


		SSHQData other;
		CMemStream dataOutput((void *)strTmp, sizeTotal);
		if (sizeTotal > 0)
		{
			dataOutput.ReadInt32(&other.iLast);
			dataOutput.ReadInt32(&other.iOpen);
			dataOutput.ReadInt32(&other.iHigh);
			dataOutput.ReadInt32(&other.iLow);
			dataOutput.ReadInt32(&other.iVolume);
			dataOutput.ReadInt32(&other.iAmount);
		}

		if (other != data)
		{
			nCurTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());

			if (other.iVolume != data.iVolume)
				bChange = true;
			data = other;
		}
		return true;
	}
}

bool CSSHQData::CheckExpired(int time)
{
	if (nCurTime == 0) return true;
	return nCurTime + nExpired <= time;
}

bool CSSHQData::CheckValid()
{
	return nStatus == 0;
}


unsigned int CSSHQData::getCollectTime()
{
	return nCollectTime;
}

std::string CSSHQData::FormatData()
{
	std::stringstream str;
	str << "last,open,high,low,volume,amount" << std::endl;
	str << data.iLast << ","
		<< data.iOpen << ","
		<< data.iHigh << ","
		<< data.iLow << ","
		<< data.iVolume << ","
		<< data.iAmount << std::endl;
	
	return str.str();
}

int CSSHQData::Compare(const CSSHQData& other)
{
	if (data == other.data)
		return 0;

	return -1;
}
